use std::{
    sync::mpsc::{SendError, Sender},
    thread::{self, JoinHandle},
};

pub struct ThreadChannel<T> {
    _join: JoinHandle<()>,
    sender: Sender<T>,
}

unsafe impl<T> Send for ThreadChannel<T> {}
unsafe impl<T> Sync for ThreadChannel<T> {}

impl<T: Send + 'static> ThreadChannel<T> {
    pub fn new(call: impl Fn(T) + Send + 'static) -> Self {
        let (sender, recev) = std::sync::mpsc::channel();
        ThreadChannel {
            sender,
            _join: thread::spawn(move || {
                while let Ok(v) = recev.recv() {
                    call(v);
                }
            }),
        }
    }
    pub fn send(&self, v: T) -> Result<(), SendError<T>> {
        self.sender.send(v)
    }
}

#[test]
fn test() {
    use crate::static_type_std::StaticTypeForStd;
    
    static S: StaticTypeForStd<ThreadChannel<i32>> = StaticTypeForStd::new(|| {
        ThreadChannel::new(|v| {
            println!("print out: {v}");
        })
    });

    S.init_static();

    S.send(1);
    S.send(2);
    S.send(3);
    S.send(4);
    std::thread::sleep(std::time::Duration::from_secs(3));
}
